package com.jfs.envent.listener;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jfs.constant.SipConstant;
import com.jfs.entity.Device;
import com.jfs.enums.RtpEnum;
import com.jfs.envent.entity.MessageDeviceInfoEntity;
import com.jfs.service.DeviceService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Description 查询到设备详情监听器
 * @E-mail cwm3412638@163.com
 * @Author cwm
 * @Date 2022/7/27
 */
@Component
@Slf4j
@AllArgsConstructor
public class DeviceInfoEventListener implements ApplicationListener<MessageDeviceInfoEntity> {
    private final DeviceService deviceService;
    private final static ReentrantLock LOCK =new ReentrantLock(true);
    @Override
    @Async
    @Transactional
    public void onApplicationEvent(MessageDeviceInfoEntity event) {
        try {
            if (log.isDebugEnabled()) {
                log.debug("【设备号:{},设备ip:{},设备端口号:{}】，查询到设备详情：{}", event.getDeviceID(), event.getIp(), event.getPort(), JSONUtil.toJsonStr(event));
            }
            LOCK.lock();
            //1. 查询设备信息
            Device device = this.deviceService.getOne(Wrappers.<Device>lambdaQuery().eq(Device::getDeviceId, event.getDeviceID()));
            if (Objects.isNull(device)) {
                //插入设备信息
                insertDevice(event);
            } else {
                //更新设备信息
               updateDevice(device,event);
            }
        } catch (Exception e) {
            log.error("设备信息查询监听器发生异常:{}", e.getMessage());
            e.printStackTrace();
        }finally {
            LOCK.unlock();
        }
    }

    /**
     * 插入设备信息
     * @param event
     */
    private void insertDevice(MessageDeviceInfoEntity event){
        Device registerDevice = new Device();
        //设备id
        registerDevice.setDeviceId(event.getDeviceID());
        //设置设备状态
        registerDevice.setOnline(true);
        //创建时间
        registerDevice.setCreateTime(DateUtil.date());
        //注册时间
        registerDevice.setRegisterTime(DateUtil.date());
        //ip
        registerDevice.setIp(event.getIp());
        //端口
        registerDevice.setPort(event.getPort());
        //固件版本
        registerDevice.setFirmware(event.getFirmware());
        //设备制造商
        registerDevice.setManufacturer(event.getManufacturer());
        //设备型号
        registerDevice.setModel(event.getModel());
        //设备名称
        registerDevice.setName(event.getDeviceName());
        //通信协议
        registerDevice.setTransport(event.getTransport());
        //数据流传输模式
        if (event.getTransport().equals(SipConstant.TRANSPORT_UDP)) {
            registerDevice.setStreamMode(RtpEnum.UDP.getName());
        } else {
            //tcp默认采用主动模式
            registerDevice.setStreamMode(RtpEnum.TCP_ACTIVE.getName());
        }
        this.deviceService.save(registerDevice);
    }

    /**
     * 更新设备信息
     * @param device
     * @param event
     */
    private void updateDevice(Device device,MessageDeviceInfoEntity event){
        device.setPort(event.getPort());
        //固件版本
        device.setFirmware(event.getFirmware());
        //设备制造商
        device.setManufacturer(event.getManufacturer());
        //设备型号
        device.setModel(event.getModel());
        //设备名称
        if (StrUtil.isEmpty(device.getName())){
            device.setName(event.getDeviceName());
        }
        //通信协议
        device.setTransport(event.getTransport());
        //数据流传输模式
        if (event.getTransport().equals(SipConstant.TRANSPORT_UDP)) {
            device.setStreamMode(RtpEnum.UDP.getName());
        } else {
            //tcp默认采用主动模式
            device.setStreamMode(RtpEnum.TCP_ACTIVE.getName());
        }
        this.deviceService.update(device, Wrappers.<Device>lambdaQuery().eq(Device::getDeviceId, event.getDeviceID()));
    }

}
